// 完成两个线程通过条件变量实现交替打印的控制

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

#define THREAD_COUNT 3

int g_num = 1;            //记录次数
int g_flag = 0;           //判断那种线程执行的标志位，0：A线程执行；1：B线程执行
pthread_mutex_t g_lock;   //次数的互斥锁
pthread_cond_t g_cond_A;  //线程A的条件变量
pthread_cond_t g_cond_B;  //线程B的条件变量

void* thread_start_A(void* arg)
{
    int* cur = (int*)arg;
    while(1)
    {
        pthread_mutex_lock(&g_lock);                          //获取互斥锁
        while(g_flag == 1)
        {
            pthread_cond_wait(&g_cond_A, &g_lock);            //进入线程等待队列，等待线程B执行
        }
        // 跳出循环，说明此时g_flag = 0
        printf("Time:%d, I'm pthread_A_%d\n",g_num++, *cur);    //执行打印
        g_flag = 1;
        pthread_cond_signal(&g_cond_B);                       //执行一次后，马上唤醒线程B
        pthread_mutex_unlock(&g_lock);                        //被唤醒后，需释放锁
        sleep(1);
    }
}

void* thread_start_B(void* arg)
{
    int* cur = (int*)arg;
    while(1)
    {
        pthread_mutex_lock(&g_lock);
        while(g_flag == 0)
        {
        pthread_cond_wait(&g_cond_B, &g_lock);
        }
        printf("Time:%d, I'm pthread_B_%d\n",g_num++, *cur);
        g_flag = 0;
        pthread_cond_signal(&g_cond_A);
        pthread_mutex_unlock(&g_lock);
        sleep(1);
    }
}


int main()
{
    pthread_mutex_init(&g_lock, NULL);  //初始化互斥锁
    pthread_cond_init(&g_cond_A, NULL);  //初始化条件变量
    pthread_cond_init(&g_cond_B, NULL);
    
    //创建线程A B，每种线程可有多个
    pthread_t A[THREAD_COUNT];  //线程A标识符组
    pthread_t B[THREAD_COUNT];  //线程B标识符组
    int i = 0;
    int*p = (int*)malloc(sizeof(int)*THREAD_COUNT);  //传递给工作线程的参数最好是堆上数据
    for(; i < THREAD_COUNT; ++i)
    {
        p[i] = i;
        int ret = pthread_create(&A[i], NULL, thread_start_A, (void*)&p[i]);
        if(ret < 0)
        {
            perror("pthread_create_A");
            return 0;
        }
        ret = pthread_create(&B[i], NULL, thread_start_B, (void*)&p[i]);
        if(ret < 0)
        {
            perror("pthread_create_B");
            return 0;
        }
    }
    
    //线程等待
    for(i = 0; i < THREAD_COUNT; ++i)
    {
        pthread_join(A[i], NULL);
        pthread_join(B[i], NULL);
    }

    //销毁堆变量
    free(p);

    //销毁互斥锁、条件变量
    pthread_mutex_destroy(&g_lock);
    pthread_cond_destroy(&g_cond_A);
    pthread_cond_destroy(&g_cond_B);

    return 0;
}
